package com.duoec.dw.lineage.service.analyser.query;

import com.alibaba.druid.sql.ast.statement.*;
import com.duoec.dw.lineage.dto.TableFieldDependencyDto;
import com.duoec.dw.lineage.dto.TableLineageDto;
import com.duoec.dw.lineage.exceptions.LineageAnalyseException;
import com.duoec.dw.lineage.dto.MultiTableLineageDto;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.LinkedHashSet;
import java.util.List;

/**
 * SQLSelectQueryBlock select analyser
 *
 * @author xuwenzhen
 */
@Service
public class SelectQueryBlockAnalyser extends BaseQueryAnalyser<SQLSelectQueryBlock> {
    /**
     * 获取当前类处理的类型
     *
     * @return SQLSelectQuery子类类型
     */
    @Override
    public Class<SQLSelectQueryBlock> getSelectQueryType() {
        return SQLSelectQueryBlock.class;
    }

    /**
     * 解析 select
     *
     * @param sqlSelectQuery      需要解析的select
     * @param withAsTableLineages with-in
     * @return 当前select语句的血缘关系
     */
    @Override
    public TableLineageDto analyse(SQLSelectQueryBlock sqlSelectQuery, MultiTableLineageDto withAsTableLineages) {
        //from
        SQLTableSource from = sqlSelectQuery.getFrom();

        MultiTableLineageDto fromTableLineages;
        if (from != null) {
            fromTableLineages = hiveAnalyser.analyseFrom(from, withAsTableLineages);
        } else {
            fromTableLineages = new MultiTableLineageDto();
        }


        TableLineageDto tableLineage = new TableLineageDto();
        if (fromTableLineages.size() == 1) {
            //如果只有一个时，直接赋值给当前表
            TableLineageDto firstTableLineage = fromTableLineages.getFirst();
            BeanUtils.copyProperties(firstTableLineage, tableLineage);
            tableLineage.setAlias(null);
        } else {
            //有多个表时，怎样处理？...
        }

        LinkedHashSet<TableFieldDependencyDto> dependencies = tableLineage.getDependencies();
        if (dependencies == null) {
            dependencies = new LinkedHashSet<>();
            tableLineage.setDependencies(dependencies);
        }

        // where
        LinkedHashSet<TableFieldDependencyDto> whereDependencies = hiveAnalyser.analyseWhere(fromTableLineages, sqlSelectQuery.getWhere());
        if (whereDependencies != null) {
            dependencies.addAll(whereDependencies);
        }

        //select
        List<SQLSelectItem> selectList = sqlSelectQuery.getSelectList();
        if (CollectionUtils.isEmpty(selectList)) {
            throw new LineageAnalyseException("当前select为空！");
        }
        selectFieldsAnalyser(tableLineage, fromTableLineages, selectList);

        //order
        hiveAnalyser.analyseOrderBy(tableLineage, fromTableLineages, sqlSelectQuery.getOrderBy());

        // group by
        hiveAnalyser.analyseGroupBy(tableLineage, fromTableLineages, sqlSelectQuery.getGroupBy());

        return tableLineage;
    }
}
